package cn.strongme.security.util;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.ttl.TransmittableThreadLocal;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.security.jwt.Jwt;
import org.springframework.security.jwt.JwtHelper;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * 用户相关工具类
 *
 * @author Walter
 */
@Slf4j
public class UserUtils {
    private static final ThreadLocal<String> THREAD_LOCAL_USER = new TransmittableThreadLocal<>();
    private static final String KEY_USER = "user";

    /**
     * 根据请求heard中的token获取用户角色
     *
     * @param httpServletRequest request
     * @return 角色名
     */
    public static List<String> getRoleList(HttpServletRequest httpServletRequest) {
        String token = getToken(httpServletRequest);
        Jwt jwt = JwtHelper.decode(token);
        JSONObject jsonObject = JSONUtil.parseObj(jwt.getClaims());
        JSONArray jsonArray = jsonObject.getJSONArray("authorities");
        List<String> result = jsonArray.toList(String.class);
        return result;
    }

    /**
     * 根据header中的token获取用户ID
     *
     * @param httpServletRequest
     * @return 用户ID
     */
    public static String getUsername(HttpServletRequest httpServletRequest) {
        String token = getToken(httpServletRequest);
        Jwt jwt = JwtHelper.decode(token);
        JSONObject jsonObject = JSONUtil.parseObj(jwt.getClaims());
        return jsonObject.getStr("user_name");
    }

    /**
     * 获取请求中token
     *
     * @param httpServletRequest request
     * @return token
     */
    public static String getToken(HttpServletRequest httpServletRequest) {
        String authorization = httpServletRequest.getHeader("Authorization");
        return StrUtil.subAfter(authorization, "Bearer ", true);
    }

    /**
     * 设置用户信息
     *
     * @param username 用户名
     */
    public static void setUsername(String username) {
        THREAD_LOCAL_USER.set(username);
        MDC.put(KEY_USER, username);
    }

    /**
     * 从threadlocal 获取用户名
     *
     * @return 用户名
     */

    public static String getUsername() {
        return THREAD_LOCAL_USER.get();
    }

    public static void clearAllUserInfo() {
        THREAD_LOCAL_USER.remove();
        MDC.remove(KEY_USER);
    }
}
